package com.example.animations.activities;

import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.example.animations.R;
import com.example.animations.controls.PathView;
import com.example.animations.controls.SliderView;

public class PathAnimationActivity extends AppCompatActivity {
    private final float minDuration = 0.1f;
    private final float maxDuration = 2f;
    private final float minRotation = 0f;
    private final float maxRotation = 360f;
    private final float minSize = 100f;
    private final float maxSize = 400f;
    private final float minStroke = 5f;
    private final float maxStroke = 50f;
    private final String ROTATION_KEY = "ROTATION_KEY";
    private final String CORNERS_KEY = "CORNERS_KEY";
    private float _duration = 1f;
    private float _rotation = 45f;
    private float _size = 300f;
    private float _stroke = 10f;
    private PathView _pathView;
    private ValueAnimator _valueAnimator;
    private PropertyValuesHolder _rotationHolder;
    private PropertyValuesHolder _cornersHolder;
    private boolean _isCircle = true;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_path_animation);

        SliderView durationSlider = findViewById(R.id.duration_slider);
        durationSlider.setTitle("Duration");
        durationSlider.setMinMaxValues(minDuration, maxDuration);
        durationSlider.setValue(_duration);
        durationSlider.onValueChanged(this::onDurationChanged);

        SliderView rotationSlider = findViewById(R.id.rotation_slider);
        rotationSlider.setTitle("Rotation");
        rotationSlider.setMinMaxValues(minRotation, maxRotation);
        rotationSlider.setValue(_rotation);
        rotationSlider.onValueChanged(this::onRotationChanged);

        SliderView sizeSlider = findViewById(R.id.size_slider);
        sizeSlider.setTitle("Size");
        sizeSlider.setMinMaxValues(minSize, maxSize);
        sizeSlider.setValue(_size);
        sizeSlider.onValueChanged(this::onSizeChanged);

        SliderView strokeSlider = findViewById(R.id.stroke_slider);
        strokeSlider.setTitle("Stroke");
        strokeSlider.setMinMaxValues(minStroke, maxStroke);
        strokeSlider.setValue(_stroke);
        strokeSlider.onValueChanged(this::onStrokeChanged);

        _pathView = findViewById(R.id.path_view);
        _pathView.initValues(_isCircle ? 0f : _rotation, _size, _stroke);

        ((Button) findViewById(R.id.play_button)).setOnClickListener(view -> startAnimation());

        _rotationHolder = PropertyValuesHolder.ofFloat(ROTATION_KEY, _rotation, 0f);
        _cornersHolder = PropertyValuesHolder.ofFloat(CORNERS_KEY, _size / 2, 0f);

        _valueAnimator = ValueAnimator.ofPropertyValuesHolder(_rotationHolder, _cornersHolder);
        _valueAnimator.addUpdateListener(this::onAnimate);
        updateAnimationDuration();
    }

    private void onDurationChanged(float duration) {
        _duration = duration;
        updateAnimationDuration();
    }

    private void onRotationChanged(float degrees) {
        _rotation = degrees;
        _pathView.setRotation(_isCircle ? 0f : _rotation);
        _rotationHolder.setFloatValues(_rotation, 0f);
    }

    private void onSizeChanged(float size) {
        _size = size;
        _cornersHolder.setFloatValues(0f, _size / 2);
        _pathView.setSize(size);
        _pathView.setCornerRadius(_isCircle ? _size / 2 : 0);
    }

    private void onStrokeChanged(float stroke) {
        _stroke = stroke;
        _pathView.setStrokeWidth(stroke);
    }

    private void startAnimation() {
        if (_isCircle) {
            _valueAnimator.reverse();
            _isCircle = false;
        } else {
            _valueAnimator.start();
            _isCircle = true;
        }
    }

    private void onAnimate(ValueAnimator valueAnimator) {
        float rotation = ((Number) valueAnimator.getAnimatedValue(ROTATION_KEY)).floatValue();
        float cornerRadius = ((Number) valueAnimator.getAnimatedValue(CORNERS_KEY)).floatValue();

        _pathView.updateAnimatedValues(rotation, cornerRadius);
    }

    private void updateAnimationDuration() {
        _valueAnimator.setDuration(Math.round(_duration * 1000));
    }
}
